package com.rags.chess.pieces;

import com.rags.chess.base.Coordinate;
import com.rags.chess.base.Piece;
import com.rags.chess.game.Game;

public class ValidMoveHelper {
	private static boolean isValidMovePiece(Game game, Coordinate source, Coordinate destination) {
		if (destination.equals(source))
			return false;
		Piece p = game.getPiece(destination);
		if (p != null && p.getColor().equals(game.getPiece(source).getColor()))
			return false;
		return true;
	}
	
	protected static boolean isValidMovePawn(Game game, Coordinate source, Coordinate destination, boolean isMoved) {
		if (!isValidMovePiece(game, source, destination))
			return false;
		if (Math.abs(destination.getColumn() - source.getColumn()) > 1 || Math.abs(destination.getRow() - source.getRow()) > 2)
			return false;
		if (isMoved && Math.abs(destination.getRow() - source.getRow()) > 1)
			return false;
		if (game.getPiece(source).isWhite() && source.getRow() >= destination.getRow())
			return false;
		if (game.getPiece(source).isBlack() && source.getRow() <= destination.getRow())
			return false;
		if (Math.abs(destination.getColumn() - source.getColumn()) == 1) {
			if (Math.abs(destination.getRow() - source.getRow()) > 1)
				return false;
			Piece destinationPiece = game.getPiece(destination); 
			if (destinationPiece == null)
				return false;
			return true;
		}
		if (game.getPiece(destination) != null)
			return false;
		if (Math.abs(destination.getRow() - source.getRow()) == 2) {
			Coordinate middle = new Coordinate((destination.getRow()+source.getRow())/2, source.getColumn());
			if (game.getPiece(middle) != null)
				return false;
		}
		return true;
	}

	protected static boolean isValidMoveKnight(Game game, Coordinate source, Coordinate destination) {
		if (!isValidMovePiece(game, source, destination))
			return false;
		if (Math.abs(destination.getRow()-source.getRow()) == 2 && Math.abs(destination.getColumn()-source.getColumn()) == 1)
			return true;
		if (Math.abs(destination.getRow()-source.getRow()) == 1 && Math.abs(destination.getColumn()-source.getColumn()) == 2)
			return true;
		return false;
	}

	protected static boolean isValidMoveBishop(Game game, Coordinate source, Coordinate destination) {
		if (!isValidMovePiece(game, source, destination))
			return false;
		if (Math.abs(destination.getRow()-source.getRow()) != Math.abs(destination.getColumn()-source.getColumn()))
			return false;
		
		int minRow = Math.min(destination.getRow(), source.getRow());
		int maxRow = Math.max(destination.getRow(), source.getRow());
		for (int i=minRow+1; i<maxRow; i++) {
			int startColumn = destination.getColumn();
			int endColumn = source.getColumn();
			if (minRow == source.getRow()) {
				startColumn = source.getColumn();
				endColumn = destination.getColumn();
			}
			if (startColumn < endColumn) {
				if (game.getSquare(new Coordinate(i, startColumn+(i-minRow))).getPiece() != null)
					return false;
			} else if (game.getSquare(new Coordinate(i, startColumn-(i-minRow))).getPiece() != null)
				return false;
		}
		return true;
	}
	
	protected static boolean isValidMoveRook(Game game, Coordinate source, Coordinate destination) {
		if (!isValidMovePiece(game, source, destination))
			return false;
		if (destination.getColumn() != source.getColumn() && destination.getRow() != source.getRow())
			return false;
		if (destination.getRow() != source.getRow()) {
			for (int i=Math.min(destination.getRow(), source.getRow())+1; i<Math.max(destination.getRow(), source.getRow()); i++)
				if (game.getPiece(new Coordinate(i, source.getColumn())) != null)
					return false;
		} else {
			for (int i=Math.min(destination.getColumn(), source.getColumn())+1; i<Math.max(destination.getColumn(), source.getColumn()); i++)
				if (game.getPiece(new Coordinate(source.getRow(), i)) != null)
					return false;
		}
		return true;
	}
	
	protected static boolean isValidMoveQueen(Game game, Coordinate source, Coordinate destination) {
		return isValidMoveBishop(game, source, destination) || isValidMoveRook(game, source, destination);
	}
	
	protected static boolean isValidMoveKing(Game game, Coordinate source, Coordinate destination) {
		if (!isValidMovePiece(game, source, destination))
			return false;
		if (Math.abs(destination.getColumn()-source.getColumn()) > 1 || Math.abs(destination.getRow()-source.getRow()) > 1)
			return false;
		return true;
	}
}
